package youxiao.bytezon.services;

import java.time.LocalDate;

import javax.persistence.EntityManager;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Join;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.Selection;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import youxiao.bytezon.models.CourseDetail;
import youxiao.bytezon.models.StudentCourseDetail;
import youxiao.bytezon.models.Teacher;
import youxiao.bytezon.repositories.CourseDetailRepository;

@Service
public class CourseDetailService {
	
	@Autowired CourseDetailRepository courseDetailRepository;
	@Autowired EntityManager entityManager;
	
	public Long getCoursesCount(Teacher teacher, LocalDate beginDate, LocalDate endDate) {
		CriteriaBuilder cb = entityManager.getCriteriaBuilder();
		
		CriteriaQuery<Long> query = cb.createQuery(Long.class);
		
		Root<CourseDetail> courseDetailRoot = query.from(CourseDetail.class);
		Selection<Long> selection = cb.countDistinct(courseDetailRoot.get("course"));
		
		Expression<Boolean> expression = cb.and(
				cb.between(courseDetailRoot.get("courseDate"), beginDate, endDate),
				cb.equal(courseDetailRoot.get("teacher"), teacher));
		
		query.select(selection).where(expression);
		return entityManager.createQuery(query).getSingleResult();
	}
	
	public Long getCourseDetailsCount(Teacher teacher, LocalDate beginDate, LocalDate endDate) {
		CriteriaBuilder cb = entityManager.getCriteriaBuilder();
		
		CriteriaQuery<Long> query = cb.createQuery(Long.class);
		
		Root<CourseDetail> courseDetailRoot = query.from(CourseDetail.class);
		Selection<Long> selection = cb.count(courseDetailRoot.get("course"));
		
		Expression<Boolean> expression = cb.and(
				cb.between(courseDetailRoot.get("courseDate"), beginDate, endDate),
				cb.equal(courseDetailRoot.get("teacher"), teacher));
		
		query.select(selection).where(expression);
		return entityManager.createQuery(query).getSingleResult();
	}
	
	public Long getStudentsCount(Teacher teacher, LocalDate beginDate, LocalDate endDate) {
		CriteriaBuilder cb = entityManager.getCriteriaBuilder();
		
		CriteriaQuery<Long> query = cb.createQuery(Long.class);
		
		Root<CourseDetail> courseDetailRoot = query.from(CourseDetail.class);
		Join<StudentCourseDetail, CourseDetail> courseDetailJoin = courseDetailRoot.join("studentCourseDetails");
		
		Selection<Long> selection = cb.countDistinct(courseDetailJoin.get("student"));
		
		Expression<Boolean> expression = cb.and(
				cb.between(courseDetailRoot.get("courseDate"), beginDate, endDate),
				cb.equal(courseDetailRoot.get("teacher"), teacher));
		
		query.select(selection).where(expression);
		return entityManager.createQuery(query).getSingleResult();
	}
	
	public Long getStudentAttendsCount(Teacher teacher, LocalDate beginDate, LocalDate endDate) {
		CriteriaBuilder cb = entityManager.getCriteriaBuilder();
		
		CriteriaQuery<Long> query = cb.createQuery(Long.class);
		
		Root<CourseDetail> courseDetailRoot = query.from(CourseDetail.class);
		Join<StudentCourseDetail, CourseDetail> courseDetailJoin = courseDetailRoot.join("studentCourseDetails");
		
		Selection<Long> selection = cb.count(courseDetailJoin.get("student"));
		
		Expression<Boolean> expression = cb.and(
				cb.between(courseDetailRoot.get("courseDate"), beginDate, endDate),
				cb.equal(courseDetailRoot.get("teacher"), teacher));
		
		query.select(selection).where(expression);
		return entityManager.createQuery(query).getSingleResult();
	}
	
}
